home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games 1996 July
/
Amiga Games 1996 #7.iso
/
userbox
/
publicdomain
/
lupe
/
source
/
lupe.c
next >
Wrap
C/C++ Source or Header
|
1996-04-08
|
38KB
|
1,284 lines
// Lupe V1.4 - 1995-96 - © Frank Toepper
// a lens
// AmigaOS 3.0+
// Maxon C++ V3
// last changes: 8.4.96
#include <stdio.h>
#include <string.h>
#include <stream.h>
#include <intuition/intuition.h>
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <intuition/gadgetclass.h>
#include <intuition/intuitionbase.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <graphics/scale.h>
#include <devices/inputevent.h>
#include <libraries/commodities.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <cybergraphics/cybergraphics.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/commodities_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/icon_protos.h>
#include <clib/cybergraphics_protos.h>
#include <pragma/cybergraphics_lib.h>
#include <wbstartup.h>
#pragma header
#define CYBERARRAY_BPP 3
#define MINWIDTH 88
#define MINHEIGHT 30
WORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
WORD scalefac = 5, maxscalefac = 15, minwidth, fixedX = 0, fixedY = 0;
WORD leftoff, topoff, bottomoff, rightoff;
WORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
WORD textoff;
ULONG cxsigflag, scrdepth;
LONG waitmask, pens[4] = {2, 3, 1, 0};
APTR VisualInfo, cyberdata = NULL;
struct MsgPort *broker_mp, *userport;
struct Task *thistask;
struct Window *mywin;
struct Screen *scr = NULL, *tmpscr;
struct Menu *menu = NULL;
struct MenuItem *item;
struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm;
struct TextFont *screenfont = NULL, *topazfont;
struct InputXpression setoriginix, resetoriginix;
struct RastPort *scrrp, destrp, *winrp;
struct Library *CxBase, *GfxBase, *GadToolsBase, *CyberGfxBase, *IconBase;
BYTE timesig;
BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE, jumpdirect;
CxObj *broker, *customcxobj;
Object *propgadget;
char pubscreenname[MAXPUBSCREENNAME];
char coordstring[12], setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r";
char title[10];
char *Template = "CX_PRIORITY=P/N/K,FAST=F/S/K,MAXSCALEFACTOR=M/N/K,SCALEFACTOR=S/N/K,"
"WINLEFT=L/N/K,WINTOP=T/N/K,WINWIDTH=W/N/K,WINHEIGHT=H/N/K,"
"COORDINATES=C/S/K,CROSSHAIR=R/S/K,SETORIGINKEY=O/K,RESETORIGINKEY=K/K,FIXED=D/S/K";
extern struct IntuitionBase *IntuitionBase;
// functions declaration for menu
BOOL jumpFunc ();
BOOL fastFunc ();
BOOL AboutFunc ();
BOOL enableFunc ();
BOOL coordsFunc ();
BOOL crosshairFunc ();
BOOL fixedFunc ();
BOOL QuitFunc ();
struct EasyStruct es_about = {
20, 0,
"Lupe",
"%s",
"%s"
};
char *era_about[] = {
"Lupe V1.4 (" __DATE__ ")\n\n"
"written by:\n"
" Frank Toepper\n"
" Maxim Gorki Strasse 5A\n"
" Greifswald\n"
" 17491\n"
" GERMANY\n\n"
"EMail:\n"
" toepper@rz.uni-greifswald.de\n\n"
"This program is Public Domain",
"Ok"
};
struct NewBroker newbroker = {
NB_VERSION,
"Lupe",
"Lupe V1.4 © 1995-96 Frank Toepper",
"A magnifing glass program.",
3,
0,
0,
NULL,
0
};
struct BitScaleArgs bsa = {
// Src Koords
0, 0,
innerwidth / scalefac,
innerheight / scalefac,
// Src Faktoren
1, 1,
0, 0,
innerwidth,
innerheight,
// Dest Faktoren
scalefac, scalefac,
// Bitmaps
NULL, NULL,
0,
0, 0,
0, 0
};
struct TextAttr topaz_attr = {
"topaz.font",
8,
0,
FPF_ROMFONT
};
void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
{
*putchdata++ = zeichen;
}
void error (char *formatstring, ...)
{
APTR args = &formatstring + 1;
struct EasyStruct easystruct = {
sizeof (struct EasyStruct),
0,
"Error",
formatstring,
"Ok"
};
if (Cli ())
{
VPrintf (formatstring, args);
FPutC (Output (), '\n');
Flush (Output ());
}
else
{
EasyRequestArgs (NULL, &easystruct, NULL, args);
}
}
BOOL lockaspublicscreen (struct Screen *screen)
{
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
if (pubscreenlist = LockPubScreenList ())
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == screen)
{
if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
{
UnlockPubScreenList ();
return TRUE;
}
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
return FALSE;
}
int setupscreen (struct Screen *selectedscreen)
{
ULONG id;
jumpdirect = FALSE;
if (selectedscreen)
{
jumpdirect = TRUE;
if (scr)
{
FreeVisualInfo (VisualInfo);
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
}
}
if (lockaspublicscreen (selectedscreen)) pubscreenlocked = TRUE;
else pubscreenlocked = FALSE;
scr = selectedscreen;
}
else if (scr)
{
if (tmpscr = scr->NextScreen)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
pubscreenlocked = FALSE;
}
if (lockaspublicscreen (tmpscr)) pubscreenlocked = TRUE;
}
else
{
error ("There is no other screen.");
return 1; // not real an error
}
scr = tmpscr;
}
else if (scr = LockPubScreen (NULL))
{
pubscreenlocked = TRUE;
}
else
{
error ("Can't lock publicscreen.");
return 2;
}
if (!(VisualInfo = GetVisualInfoA (scr, NULL)))
{
error ("Can't get visualinfo from screen.");
return 3;
}
cybergfxscreen = FALSE;
if (CyberGfxBase)
if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
if (IsCyberModeID (id))
if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
cybergfxscreen = TRUE;
return 0;
}
void CloseDownScreen ()
{
if (VisualInfo)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
}
if (scr && pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
scr = NULL;
}
}
void getoffsets ()
{
struct DrawInfo *drawinfo;
APTR sizeobject;
ULONG attr;
if (screenfont)
{
CloseFont (screenfont);
screenfont = NULL;
}
hires = (scr->Flags & SCREENHIRES) != 0;
hires ? (rightoff = 18) : (rightoff = 13);
if (drawinfo = GetScreenDrawInfo (scr))
{
if (sizeobject = NewObject (NULL, SYSICLASS,
SYSIA_Which, SIZEIMAGE,
SYSIA_DrawInfo, drawinfo,
SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES,
TAG_END))
{
if (GetAttr (IA_Width, sizeobject, &attr))
{
sizeiw = attr;
rightoff = (UWORD) attr;
}
if (GetAttr (IA_Height, sizeobject, &attr))
{
sizeih = attr;
}
newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
DisposeObject (sizeobject);
}
pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
pens[1] = drawinfo->dri_Pens[FILLPEN];
pens[2] = drawinfo->dri_Pens[TEXTPEN];
pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
FreeScreenDrawInfo (scr, drawinfo);
}
scrrp = &scr->RastPort;
topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
leftoff = scr->WBorLeft;
scrbm = scrrp->BitMap;
scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
minwidth = MINWIDTH;
if (coords)
{
bottomoff = sizeih;
// center the text in the bottomborder
textoff = (bottomoff + topazfont->tf_YSize >> 1) - topazfont->tf_Baseline;
// SysIHack or height of screenfont <= 8?
if ((bottomoff - 2) >= scr->Font->ta_YSize)
{
if (screenfont = OpenFont (scr->Font))
{
minwidth = 11 * (screenfont->tf_XSize);
// center the text in the bottomborder
textoff = (bottomoff + screenfont->tf_YSize >> 1) - screenfont->tf_Baseline;
}
}
}
else bottomoff = scr->WBorBottom;
}
void setwintitle ()
{
LONG args[] = { (LONG) "Lupe", scalefac };
RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
SetWindowTitles (mywin, title, (STRPTR) ~0);
}
int allocbm ()
{
if (destbm) FreeBitMap (destbm);
if (srcbm) FreeBitMap (srcbm);
destbm = srcbm = NULL;
if (cyberdata) FreeVec (cyberdata);
cyberdata = NULL;
winx = mywin->Width;
winy = mywin->Height;
innerwidth = winx - (leftoff + rightoff);
innerheight = winy - (topoff + bottomoff);
sourcewidth = innerwidth / scalefac;
sourceheight = innerheight / scalefac;
if (scalefac > 1)
{
if (cybergfxscreen)
{
if (!(cyberdata = AllocVec (sourcewidth * sourceheight * CYBERARRAY_BPP, MEMF_PUBLIC)))
{
error ("Can't allocate %ld Bytes for CyberPixelArray.", sourcewidth * sourceheight * CYBERARRAY_BPP);
return 1;
}
if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR | BMF_MINPLANES, scrbm)))
{
error ("'AllocBitMap' for destination bitmap failed.");
return 3;
}
}
else
{
if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, scrdepth, BMF_CLEAR, scrbm)))
{
error ("'AllocBitMap' for source bitmap failed.");
return 2;
}
if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, scrbm)))
{
error ("'AllocBitMap' for destination bitmap failed.");
return 3;
}
bsa.bsa_SrcWidth = sourcewidth;
bsa.bsa_SrcHeight = sourceheight;
bsa.bsa_DestWidth = innerwidth;
bsa.bsa_DestHeight = innerheight;
bsa.bsa_SrcBitMap = srcbm;
bsa.bsa_DestBitMap = destbm;
bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
}
destrp.BitMap = destbm;
}
return 0;
}
BOOL makescreensmenu ()
{
struct NewMenu tmpmenu[] = {
{ NM_SUB, 0, 0, 0, 0, 0 },
{ NM_END, 0, 0, 0, 0, 0 }
};
ULONG lock;
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
int i = 0;
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
if (tmpscr->NextScreen)
{
while (tmpscr = tmpscr->NextScreen)
{
tmpmenu[0].nm_Label = tmpscr->DefaultTitle;
if (pubscreenlist = LockPubScreenList ())
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == tmpscr)
{
tmpmenu[0].nm_Label = pubscreennode->psn_Node.ln_Name;
break;
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
tmpmenu[0].nm_UserData = tmpscr;
// each item single created
if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
{
itempointer = &(*itempointer)->NextItem;
}
else error ("Can't create a screensmenu item.");
}
}
else
{
tmpmenu[0].nm_Label = "No Other Screen";
if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
{
(*itempointer)->Flags |= HIGHNONE;
itempointer = &(*itempointer)->NextItem;
}
else error ("Can't create screensmenu.");
}
UnlockIBase (lock);
if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
{
return TRUE;
}
else error ("Can't layout screensmenu.");
return FALSE;
}
void freescreensmenu (struct MenuItem *menuitem)
{
if (menuitem)
{
freescreensmenu (menuitem->NextItem);
FreeMenus ((struct Menu *) menuitem);
}
}
BOOL openwin ()
{
ULONG lock;
WORD bw, rh;
struct Rectangle zoom = {
minwidth + leftoff + rightoff,
MINHEIGHT + topoff + bottomoff + sizeih,
-1, -1
};
struct NewMenu standartmenu[] = {
{ NM_TITLE, "Project", 0, 0, 0, 0 },
{ NM_ITEM, "Jump", "J", 0, 0, jumpFunc },
{ NM_ITEM, "Jump To Screen", 0, 0, 0, 0 },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "Enable", "E", (enable ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, enableFunc },
{ NM_ITEM, "Fixed", "D", (fixed ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fixedFunc },
{ NM_ITEM, "Fast", "F", (fast ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fastFunc },
{ NM_ITEM, "Coordinates", "C", (coords ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, coordsFunc },
{ NM_ITEM, "Crosshair", "R", (crosshair ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, crosshairFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "About", "?", 0, 0, AboutFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "Quit", "Q", 0, 0, QuitFunc },
{ NM_END, 0, 0, 0, 0, 0 }
};
if (hires) bw = rh = 2;
else bw = rh = 1;
// first bring the screen to front
// -> screen order in menu correct
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
UnlockIBase (lock);
if (tmpscr != scr)
{
if (jumpdirect) ScreenToFront (scr);
else ScreenToBack (tmpscr);
}
if (menu = CreateMenusA (standartmenu, NULL))
{
if (makescreensmenu ())
{
if (propgadget = (Object *) NewObject (NULL, PROPGCLASS,
PGA_Freedom, FREEVERT,
ICA_TARGET, ICTARGET_IDCMP,
PGA_NewLook, TRUE,
PGA_Borderless, newlook,
PGA_Total, maxscalefac,
PGA_Visible, 1,
PGA_Top, scalefac - 1,
GA_RelRight, bw - sizeiw + 3,
GA_Top, topoff + rh,
GA_Width, sizeiw - bw - bw - 4,
GA_RelHeight, -topoff - sizeih - rh - rh,
GA_RightBorder, TRUE,
TAG_DONE))
{
if (mywin = OpenWindowTags (NULL,
WA_Flags, WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET | WFLG_DRAGBAR
| WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH | WFLG_NEWLOOKMENUS
| WFLG_NOCAREREFRESH | WFLG_REPORTMOUSE
| WFLG_SIZEBRIGHT | (coords ? WFLG_SIZEBBOTTOM : 0),
WA_AutoAdjust, 1,
WA_MaxHeight, -1,
WA_MaxWidth, -1,
WA_MinHeight, MINHEIGHT + topoff + bottomoff,
WA_MinWidth, minwidth + leftoff + rightoff,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE | IDCMP_MENUPICK
| IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY,
WA_InnerHeight, innerheight,
WA_InnerWidth, innerwidth,
WA_Left, winleft,
WA_Gadgets, propgadget,
WA_Top, wintop,
WA_PubScreen, scr,
WA_Zoom, &zoom,
TAG_DONE))
{
// shit patches
leftoff = mywin->BorderLeft;
bottomoff = mywin->BorderBottom;
SetMenuStrip (mywin, menu);
setwintitle ();
userport = mywin->UserPort;
winrp = mywin->RPort;
if (screenfont) SetFont (winrp, screenfont);
else SetFont (winrp, topazfont);
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
return TRUE;
}
else error ("Can't open window.");
}
else error ("Can't create propgadget.");
}
}
else error ("Can't create menu.");
return FALSE;
}
void closewin ()
{
if (menu) ClearMenuStrip (mywin);
CloseWindow (mywin);
if (menu)
{
freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
FreeMenus (menu);
menu = NULL;
}
DisposeObject (propgadget);
if (srcbm) FreeBitMap (srcbm);
if (destbm) FreeBitMap (destbm);
if (cyberdata) FreeVec (cyberdata);
srcbm = NULL;
destbm = NULL;
cyberdata = NULL;
}
void refresh ()
{
WORD x, y, xoff = 0, yoff = 0;
if (fixed)
{
x = fixedX;
y = fixedY;
}
else
{
x = scr->MouseX;
y = scr->MouseY;
}
// print the coordinates
if (coords)
{
LONG args[] = {x - originX, y - originY};
memset (coordstring, ' ', 11);
RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, coordstring);
coordstring[strlen (coordstring)] = ' ';
Move (winrp, leftoff, mywin->Height - textoff);
Text (winrp, coordstring, 11);
}
// adjust the coordinates
x -= sourcewidth >> 1;
y -= sourceheight >> 1;
if (x < 0)
{
xoff = x;
x = 0;
}
else if (x > (scr->Width - sourcewidth))
{
xoff = -(scr->Width - sourcewidth - x);
x = scr->Width - sourcewidth;
}
if (y < 0)
{
yoff = y;
y = 0;
}
else if (y > (scr->Height - sourceheight))
{
yoff = -(scr->Height - sourceheight - y);
y = scr->Height - sourceheight;
}
// calculate the crosshair
if (crosshair)
{
xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac >> 1);
yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac >> 1);
}
if (scalefac > 1)
{
// blit and scale
if (cybergfxscreen)
{
// BitMapScale don't work with bitmaps >8 Bit (CyberGfx 2.15)
ReadPixelArray (cyberdata, 0, 0, sourcewidth * CYBERARRAY_BPP, scrrp, x, y, sourcewidth, sourceheight, RECTFMT_RGB);
ScalePixelArray (cyberdata, sourcewidth, sourceheight, sourcewidth * CYBERARRAY_BPP, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac, RECTFMT_RGB);
}
else
{
BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
BitMapScale (&bsa);
}
// draw the crosshair
if (crosshair)
{
Move (&destrp, xoff, 0);
Draw (&destrp, xoff, sourceheight * scalefac - 1);
Move (&destrp, 0, yoff);
Draw (&destrp, sourcewidth * scalefac - 1, yoff);
}
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
mywin->Flags |= SIZEGADGET;
}
else
{
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
// draw the crosshair in 1:1 - mode
if (crosshair)
{
SetDrMd (winrp, COMPLEMENT);
Move (winrp, leftoff + xoff, topoff);
Draw (winrp, leftoff + xoff, topoff + innerheight - 1);
Move (winrp, leftoff, topoff + yoff);
Draw (winrp, leftoff + innerwidth - 1, topoff + yoff);
SetDrMd (winrp, JAM2);
}
}
mywin->Flags |= SIZEGADGET;
}
}
void CxFunction (CxMsg *cxm, CxObj *co)
{
struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
if (origin)
{
if (MatchIX (ie, &setoriginix))
{
originX = scr->MouseX;
originY = scr->MouseY;
DisposeCxMsg (cxm);
return;
}
if (MatchIX (ie, &resetoriginix))
{
originX = originY = 0;
DisposeCxMsg (cxm);
return;
}
}
if ((ie->ie_Class == IECLASS_TIMER) || fast)
Signal (thistask, 1 << timesig);
}
BOOL initbroker ()
{
LONG errorcode;
if (broker_mp = CreateMsgPort ())
{
newbroker.nb_Port = broker_mp;
cxsigflag = 1 << broker_mp->mp_SigBit;
if (broker = CxBroker (&newbroker, &errorcode))
{
if (customcxobj = CxCustom (CxFunction, 0))
{
if (!CxObjError (customcxobj))
{
AttachCxObj (broker, customcxobj);
if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
{
origin = FALSE;
error ("Can't init Hotkeys.\n'Set Origin' disabled.");
}
ActivateCxObj (broker, 1);
return TRUE;
}
DeleteCxObj (customcxobj);
}
else error ("Can't create commodity-custom-objekt.");
DeleteCxObjAll (broker);
}
else if (errorcode == CBERR_SYSERR)
error ("Can't create commodity-broker-objekt.");
DeleteMsgPort (broker_mp);
}
else error ("Can't create messageport for commodity-broker");
return FALSE;
}
// enable-flag only
void setmenu ()
{
struct MenuItem *mitem;
ClearMenuStrip (mywin);
mitem = ItemAddress (menu, FULLMENUNUM (0, 3, NOSUB));
if (enable) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
ResetMenuStrip (mywin, menu);
}
BOOL reopenwin ()
{
waitmask &= ~(1 << userport->mp_SigBit);
wintop = mywin->TopEdge;
winleft = mywin->LeftEdge;
closewin ();
getoffsets ();
if (!openwin ()) return FALSE;
waitmask |= 1 << userport->mp_SigBit;
if (allocbm ()) return FALSE;
jump = TRUE;
return TRUE;
}
BOOL setpropgad ()
{
if (allocbm ()) return FALSE;
SetAttrs (propgadget, PGA_Top, scalefac - 1);
RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
setwintitle ();
return TRUE;
}
void processmsg ()
{
struct IntuiMessage *intuimsg = NULL, m;
CxMsg *msg;
BOOL cont = TRUE, fixedmove = FALSE;
LONG sigmask, msgid, msgtype;;
UWORD code;
ULONG lock;
static BOOL (*func)();
waitmask = (1 << userport->mp_SigBit) | (1 << timesig) | cxsigflag | SIGBREAKF_CTRL_C;
while (cont)
{
sigmask = Wait (waitmask);
if (sigmask & cxsigflag)
{
while (msg = (CxMsg *) GetMsg (broker_mp))
{
msgid = CxMsgID (msg);
msgtype = CxMsgType (msg);
ReplyMsg ((struct Message *) msg);
switch (msgtype)
{
case CXM_COMMAND:
switch (msgid)
{
case CXCMD_DISABLE:
ActivateCxObj (broker, 0);
enable = FALSE;
setmenu ();
break;
case CXCMD_ENABLE:
ActivateCxObj (broker, 1);
enable = TRUE;
setmenu ();
break;
case CXCMD_UNIQUE:
case CXCMD_KILL:
cont = FALSE;
break;
}
}
}
}
if (sigmask & (1 << userport->mp_SigBit))
{
jump = FALSE;
while (intuimsg = (struct IntuiMessage *) GetMsg (userport))
{
CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
ReplyMsg ((struct Message *) intuimsg);
switch (m.Class)
{
case IDCMP_CLOSEWINDOW:
cont = FALSE;
break;
case IDCMP_NEWSIZE:
if (allocbm ()) cont = FALSE;
break;
case IDCMP_IDCMPUPDATE:
ULONG h;
GetAttr (PGA_Top, propgadget, &h);
if (++h != scalefac)
{
scalefac = h;
if (allocbm ()) cont = FALSE;
setwintitle ();
}
break;
case IDCMP_MENUPICK:
code = m.Code;
while ((code != MENUNULL) && cont && !jump)
{
item = ItemAddress (menu, code);
if (SUBNUM (code) != NOSUB)
{
if (GTMENUITEM_USERDATA (item)) // 'no other screen' - submenu
{
try
{
if (setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item))) throw 1;
waitmask &= ~(1 << userport->mp_SigBit);
wintop = mywin->TopEdge;
winleft = mywin->LeftEdge;
closewin ();
getoffsets ();
if (!openwin ()) throw 2;
waitmask |= 1 << userport->mp_SigBit;
if (allocbm ()) throw 3;
}
catch (int)
{
cont = FALSE;
}
jump = TRUE;
}
}
else
{
func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
cont = func ();
}
if (!jump) code = item->NextSelect;
}
break;
case IDCMP_ACTIVEWINDOW:
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
ClearMenuStrip (mywin);
freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
if (makescreensmenu ()) SetMenuStrip (mywin, menu);
else cont = FALSE;
break;
case IDCMP_INACTIVEWINDOW:
SetAPen (winrp, pens[2]);
SetBPen (winrp, pens[3]);
break;
case IDCMP_MOUSEBUTTONS:
if (fixed)
{
if (m.Code == SELECTDOWN) fixedmove = TRUE;
else fixedmove = FALSE;
}
break;
case IDCMP_MOUSEMOVE:
if (fixedmove)
{
fixedX = scr->MouseX;
fixedY = scr->MouseY;
}
break;
case IDCMP_VANILLAKEY:
switch (m.Code)
{
case 'J':
case 'j':
cont = jumpFunc ();
break;
case 'E':
case 'e':
enable = !enable;
ActivateCxObj (broker, enable);
setmenu ();
case 'F':
case 'f':
fast = !fast;
break;
case 'C':
case 'c':
coords = !coords;
cont = reopenwin ();
break;
case 'R':
case 'r':
crosshair = !crosshair;
break;
case 'O':
case 'o':
originX = scr->MouseX;
originY = scr->MouseY;
break;
case 'K':
case 'k':
originX = originY = 0;
break;
case 'D':
case 'd':
fixed = !fixed;
break;
case '?':
case 'A':
case 'a':
AboutFunc ();
break;
case 'Q':
case 'q':
case 27:
cont = FALSE;
break;
case '+':
if (scalefac < maxscalefac)
{
scalefac++;
cont = setpropgad ();
}
break;
case '-':
if (scalefac > 1)
{
scalefac--;
cont = setpropgad ();
}
break;
}
break;
case IDCMP_RAWKEY:
switch (m.Code)
{
// up
case 76:
if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY -= sourceheight - 1;
if (fixedY < 0) fixedY = 0;
}
else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = 0;
}
else if (fixedY) fixedY--;
break;
// down
case 77:
if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY += sourceheight - 1;
if (fixedY > (scr->Height - 1)) fixedY = scr->Height - 1;
}
else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = scr->Height - 1;
}
else if (fixedY < (scr->Height - 1)) fixedY++;
break;
// right
case 78:
if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX += sourcewidth - 1;
if (fixedX > (scr->Width - 1)) fixedX = scr->Width - 1;
}
else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = scr->Width - 1;
}
else if (fixedX < (scr->Width - 1)) fixedX++;
break;
// left
case 79:
if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX -= sourcewidth - 1;
if (fixedX < 0) fixedX = 0;
}
else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = 0;
}
else if (fixedX) fixedX--;
break;
}
}
}
}
if ((sigmask & (1 << timesig)) && cont)
{
// refresh only if we living on the active screen
lock = LockIBase (0);
tmpscr = IntuitionBase->ActiveScreen;
UnlockIBase (lock);
if (scr == tmpscr) refresh ();
}
if (sigmask & SIGBREAKF_CTRL_C)
{
cont = FALSE;
}
}
}
BOOL checkmenuitem (BOOL &value)
{
if (!value && (item->Flags & CHECKED)) value = TRUE;
else if (value && !(item->Flags & CHECKED)) value = FALSE;
return TRUE;
}
BOOL fixedFunc ()
{
return checkmenuitem (fixed);
}
BOOL fastFunc ()
{
return checkmenuitem (fast);
}
BOOL crosshairFunc ()
{
return checkmenuitem (crosshair);
}
BOOL AboutFunc ()
{
EasyRequestArgs (NULL, &es_about, NULL, era_about);
return TRUE;
}
BOOL jumpFunc ()
{
int returnvalue;
if (!(returnvalue = setupscreen (NULL)))
{
return reopenwin ();
}
else if (returnvalue == 1) return TRUE; // no other screen
return FALSE;
}
BOOL coordsFunc ()
{
if (!coords && (item->Flags & CHECKED)) coords = TRUE;
else if (coords && !(item->Flags & CHECKED)) coords = FALSE;
else return TRUE; // nothing changed
return reopenwin ();
}
BOOL enableFunc ()
{
if (item->Flags & CHECKED)
{
ActivateCxObj (broker, 1);
enable = TRUE;
}
else if (!(item->Flags & CHECKED))
{
ActivateCxObj (broker, 0);
enable = FALSE;
}
return TRUE;
}
BOOL QuitFunc ()
{
return FALSE;
}
BOOL argbool (char **argv, char *name, BOOL def)
{
char *value;
if (value = (char *) FindToolType ((UBYTE **) argv, name))
{
if ((MatchToolValue (value, "YES")) || (MatchToolValue (value, "ON"))) return TRUE;
if ((MatchToolValue (value, "OFF")) || (MatchToolValue (value, "NO"))) return FALSE;
}
return def;
}
LONG argint (char **argv, UBYTE *name, LONG def)
{
APTR value;
LONG returnvalue;
if (value = FindToolType ((UBYTE **) argv, name))
if (StrToLong ((UBYTE *) value, &returnvalue)) return returnvalue;
return def;
}
void argstring (char *result, char **argv, char *name)
{
char *value;
if (value = FindToolType ((UBYTE **) argv, name))
strncpy (result, value, 50);
}
void readargs ()
{
// first time always the tooltypes will be evaluated
// if we started from Cli the tooltypes can be overloaded
char programname[32];
char **argv;
struct DiskObject *programicon;
struct RDArgs * rdargs;
LONG args[13];
struct DrawInfo *drawinfo;
wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
// make window as square as possible
if (drawinfo = GetScreenDrawInfo (scr))
{
innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
FreeScreenDrawInfo (scr, drawinfo);
}
// a Maxon C++ flag (wbstartup.h)
if (_wbflag) strcpy (programname, thistask->tc_Node.ln_Name);
else GetProgramName (programname, 32);
if (IconBase = OpenLibrary ("icon.library", 37))
{
if (programicon = GetDiskObject (programname))
{
argv = programicon->do_ToolTypes;
newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
fast = argbool (argv, "Fast", fast);
maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
scalefac = argint (argv, "ScaleFactor", scalefac);
winleft = argint (argv, "WinLeft", winleft);
wintop = argint (argv, "WinTop", wintop);
innerheight = argint (argv, "WinHeight", innerheight);
innerwidth = argint (argv, "WinWidth", innerwidth);
coords = argbool (argv, "Coordinates", coords);
crosshair = argbool (argv, "Crosshair", crosshair);
argstring (setoriginkey, argv, "SetOriginKey");
argstring (resetoriginkey, argv, "ResetOriginKey");
argbool (argv, "Fixed", fixed);
FreeDiskObject (programicon);
}
CloseLibrary (IconBase);
}
if (Cli ())
{
memset (args, '\0', sizeof (args));
args[1] = fast;
args[8] = coords;
args[9] = crosshair;
args[12] = fixed;
if (rdargs = ReadArgs (Template, args, NULL))
{
if (args[0]) newbroker.nb_Pri = *(LONG *) args[0];
fast = args[1];
if (args[2]) maxscalefac = *(LONG *) args[2];
if (args[3]) scalefac = *(LONG *) args[3];
if (args[4]) winleft = *(LONG *) args[4];
if (args[5]) wintop = *(LONG *) args[5];
if (args[6]) innerwidth = *(LONG *) args[6];
if (args[7]) innerheight = *(LONG *) args[7];
coords = args[8];
crosshair = args[9];
if (args[10]) strcpy (setoriginkey, (char *) args[10]);
if (args[11]) strcpy (resetoriginkey, (char *) args[11]);
fixed = args[12];
FreeArgs (rdargs);
}
}
if (maxscalefac < 5) maxscalefac = 5;
// not lower than innerheight or innerwidth
// otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
// can go to 0 -> 'AllocBitMap ()' failed
if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
if (scalefac > maxscalefac) scalefac = maxscalefac;
if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
}
void main ()
{
if (CxBase = OpenLibrary ("commodities.library", 37))
{
if (GfxBase = OpenLibrary ("graphics.library", 39))
{
if (GadToolsBase = OpenLibrary ("gadtools.library", 37))
{
CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
InitRastPort (&destrp);
SetDrMd (&destrp, COMPLEMENT);
thistask = FindTask (NULL);
if (topazfont = OpenFont (&topaz_attr))
{
if (!setupscreen (NULL))
{
readargs ();
getoffsets ();
if (openwin ())
{
if (!allocbm ())
{
if ((timesig = AllocSignal (-1L)) != -1)
{
if (initbroker ())
{
processmsg ();
DeleteCxObjAll (broker);
DeleteMsgPort (broker_mp);
}
FreeSignal (timesig);
}
else error ("Can't allocate signal");
}
closewin ();
}
CloseDownScreen ();
}
CloseFont (topazfont);
if (screenfont) CloseFont (screenfont);
}
else error ("Can't open Topas.font");
if (CyberGfxBase) CloseLibrary (CyberGfxBase);
CloseLibrary (GadToolsBase);
}
else error ("can't open '%s' version %ld or higher.", "gadtools.library", 37L);
CloseLibrary (GfxBase);
}
else error ("can't open '%s' version %ld or higher.", "graphics.library", 39L);
CloseLibrary (CxBase);
}
else error ("can't open '%s' version %ld or higher.", "commodities.library", 37L);
}